package question5.com.qee.jdbc;

import org.springframework.util.CollectionUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ProjectName: learning
 * @Package: question5.com.qee.jdbc
 * @ClassName: DefaultSession
 * @Description:
 * @Date: 2021/10/20 4:59 下午
 * @Version: 1.0
 */
public class DefaultSession extends ConnectionHolder implements Session {

    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");





    public static void main(String[] args) {
        Matcher matcher = insertPattern.matcher("insert into tb_name ( c1,c2) values (#{v1},#{v2},#{v3}),(#{v1},#{v2},#{v3})");

        System.out.println(matcher.matches());
        System.out.println(matcher.group(1));

        Matcher matcher1 = getValuePattern.matcher("insert into tb_name ( c1,c2) values (#{v1},#{v2},#{v3}),(#{v1},#{v2},#{v3})");
        while (matcher1.find()) {
            String group = matcher1.group(1);
            System.out.println(group);
            String ss = matcher1.replaceFirst(group);
            System.out.println(ss);

            //replaceFirst 会重置 matcher1
            matcher1.reset(ss);
        }

    }


    @Override
    public <T> List<T> selectList(String sql, Map<String, Object> paramMap, Class<T> resultType) throws SQLException, IllegalAccessException, InstantiationException {
        try (Statement statement = createStatement()) {
            if (!CollectionUtils.isEmpty(paramMap)) {
                for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                    sql = sql.replace("#{" + entry.getKey() + "}", entry.getValue().toString());
                }
            }
            statement.execute(sql);
            ResultSet resultSet = statement.getResultSet();

            List<T> result = getResult(resultType, resultSet);
            return result;
        }
    }


    @Override
    public <T> T selectOne(String sql, Map<String, Object> paramMap, Class<T> resultType) throws IllegalAccessException, SQLException, InstantiationException {

        List<T> selectList = selectList(sql, paramMap, resultType);
        if (selectList.size() == 0) {
            return null;
        }
        return selectList.get(0);
    }

    // insert into tb_name(c1,c2,..cn) values(?,?,?,);

    @Override
    public int insert(String sql, Map<String, Object> paramMap) throws SQLException {
        List<Map<String, Object>> paramList = new ArrayList<>();
        paramList.add(paramMap);
        return batchInsert(sql, paramList);
    }

    //insert into tb_name(c1,c2,..cn) values(?,?,?,?),(?,?,?,?);

    @Override
    public int batchInsert(String sql, List<Map<String, Object>> paramList) throws SQLException {
        Matcher matcher = insertPattern.matcher(sql);
        if (!matcher.matches()) {
            throw new RuntimeException("sql error");
        }
        String tableCln = matcher.group(1);
        String[] colns = tableCln.split(",");
        try (Statement statement = createStatement()) {
            Matcher valueMatcher = getValuePattern.matcher(sql);
            for (Map<String, Object> paramMap : paramList) {
                int size = colns.length;
                while (size != 0 && valueMatcher.find()) {
                    String group = valueMatcher.group(1);
                    Object val = paramMap.get(group);
                    if (val instanceof String) {
                        val = "'" + val + "'";
                    }
                    if (val instanceof Date) {
                        val = "'" + sdf.format(val) + "'";
                    }
                    sql = valueMatcher.replaceFirst(val.toString());
                    valueMatcher.reset(sql);
                    size--;
                }
            }
            System.out.println(sql);
            statement.execute(sql);
            return statement.getUpdateCount();
        }
    }

    @Override
    public int update(String sql, Map<String, Object> paramMap) throws SQLException {
        try (Statement statement = createStatement()) {
            if (!CollectionUtils.isEmpty(paramMap)) {
                for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
                    String val = entry.getValue().toString();
                    if (entry.getValue() instanceof Date) {
                        val = "'" + sdf.format(entry.getValue()) + "'";
                    }
                    if (entry.getValue() instanceof String) {
                        val = "'" + val + "'";
                    }
                    sql = sql.replace("#{" + entry.getKey() + "}", val);
                }
            }

            System.out.println(sql);
            statement.execute(sql);
            return statement.getUpdateCount();
        }
    }
}
